package feed

import (
	"encoding/json"
	"os"
    "time"

	"code.google.com/awwwe-browser/auralvm/param"
	"code.google.com/awwwe-browser/data"
	"code.google.com/awwwe-browser/slurp"
)

// FeedItem is an article linked to in a feed that the user has or has not read.
// FeedItem.Time is the last time the article was viewed by the user.
type FeedItem struct {
    Guid string // unique never changes
    Time string // last date/time user viewed
}

func (this FeedItem)updateViewed() {
    this.setTime(time.Now())
}

func (this FeedItem)setTime(t time.Time) {
    this.Time = t.Format(time.RFC3339)
}

func (this FeedItem)time() time.Time {
    var t time.Time
    t, _ = time.Parse(time.RFC3339, this.Time)
    return t
}

func parseATOMTime(src string) time.Time {
	var t time.Time
    var err error
    t, err = time.Parse(atomTimeLayout, src)
    if err != nil {
        t = time.Now()
    }
    return t
}

func parseRSSTime(src string) time.Time {
	var t time.Time
    var err error
    t, err = time.Parse(rssTimeLayout, src)
    if err != nil {
        t = time.Now()
    }
    return t
}

// a feed slice
type SliceFeedItem struct {
	data.SlicerBase
}

// a cmp method for feeds
func cmpFeedItem(i1 interface{}, i2 interface{}) int {
	if i1.(*FeedItem).Guid == i2.(*FeedItem).Guid {
		return 0
	}
    return -1
}

// BuildSliceFeedItem constructs a SliceFeedItem.
func BuildSliceFeedItem(length, capacity int) SliceFeedItem {
	var v SliceFeedItem
	v.Init(length, capacity, cmpFeedItem)
	return v
}

// Returns the slice's element at the slice's index.
// Param index is the index of the slice.
func (this *SliceFeedItem) AtIndex(index int) *FeedItem {
	var ifc interface{}
    ifc = this.SlicerBase.AtIndex(index)
    if ifc != nil {
        return ifc.(*FeedItem)
    } else {
        return nil
    }
}

// Remove gets an item at index
// Deletes the item at index form the array
// Returns the item.
func (this *SliceFeedItem) Remove(index int) *FeedItem {
	var ifc interface{}
	ifc = this.SlicerBase.Remove(index)
    if ifc != nil {
		return ifc.(*FeedItem)
    }
    return nil
}

// Appends a slice of feeds to the slice.
func (this *SliceFeedItem) AppendSlice(src []FeedItem) {
	var v FeedItem
    for _, v = range src {
    	this.Append(&v)
    }
}

// Returns the data as a slice.
func (this *SliceFeedItem) Slice() []*FeedItem {
	var i, length int
	var item interface{}
	var ss []*FeedItem
	length = len(this.Data)
	ss = make([]*FeedItem, length, length)
	for i, item = range this.Data {
		ss[i] = item.(*FeedItem)
	}
	return ss
}

// Save writes the slice to the file.
func (this *SliceFeedItem) Save() error {
	var markup []byte
	var err error
	var file *os.File
	markup, err = json.MarshalIndent(this.Slice(), "", "  ")
	if err == nil {
		file, err = os.Create(param.LocalFeedItemFilePath)
		defer file.Close()
		if err == nil {
			_, err = file.Write(markup)
		}
	}
	return err
}

// GetFeedItems reads the slice from the file.
func GetFeedItems() *SliceFeedItem {
	var slicefi SliceFeedItem
	var feeds []FeedItem
	var markup []byte
	var err error
	feeds = make([]FeedItem, 0, 5)
	slicefi = BuildSliceFeedItem(0, 20)
	markup, err = slurp.SlurpFile(param.LocalFeedItemFilePath)
	if err == nil {
		err = json.Unmarshal(markup, &feeds)
		if err == nil {
			slicefi.AppendSlice(feeds)
		}
	}
	return &slicefi
}

// UpdateItemViewed sets the Time of a feed item to now and saves the slice.
func (this *SliceFeedItem) UpdateItemViewed(id string) {
    var i, length int
    var item *FeedItem
    length = this.Len()
    for i = 0; i < length; i++ {
        item = this.AtIndex(i)
        if item.Guid == id {
            item.updateViewed()
            this.Save()
            return
        }
    }
    item.Guid = id
    item.updateViewed()
    this.Save()
    return
}
